package dm.ast;

import test.envset.GlobalState;

import java.util.ArrayList;
import java.util.List;

public class DmGroupby extends DmASTNode {

    public List<DmExpression> groupbyItems = null;
    private int itemSize = 0;
    public int cubeOrrollupOrGroupingsets = 0; //0表示cube和rollup都为false 1表示cube为true
    public List<Integer> groupingSets = null;

    public DmGroupby() {
        groupingSets = new ArrayList<>();
        groupbyItems = new ArrayList<DmExpression>();
    }

    public void setItemSize(int groups) {
        this.itemSize = groups;
    }

    public int getItemSize() {
        return itemSize;
    }

    public void setGroupingSets(List<Integer> groupingSets) {
        this.groupingSets = groupingSets;
    }

    @Override
    public void setWidt() {
        if (itemSize == 0) {
            wid_t = 0;
        } else {
            wid_t = itemSize;//未填充时,groupby子句的宽度
            if (groupbyItems.size() != 0) { //填充后,groupby子句的宽度
                wid_t = 0;
                for (int i = 0; i < groupbyItems.size(); i++) {
                    groupbyItems.get(i).setWidt();
                    wid_t += groupbyItems.get(i).wid_t;
                }
            }
        }
    }

    @Override
    public void setDept() {
        if (itemSize == 0) {
            dep_t = 0;
        } else {
            dep_t = 1;//未填充时,groupby子句的深度
            if (groupbyItems.size() != 0) {//填充后,groupby子句的深度
                for (int i = 0; i < groupbyItems.size(); i++) {
                    groupbyItems.get(i).setDept();
                    if (groupbyItems.get(i).dep_t > dep_t) {
                        dep_t = groupbyItems.get(i).dep_t;
                    }
                }
            }
        }
    }

    @Override
    public DmDataType getExpressionType() {
        //todo Auto-generated method stub
        return null;
    }

    @Override
    public String toSql() {
        if (groupbyItems == null || itemSize == 0) {
            return " " + this.getClass().getSimpleName();
        } else {
            StringBuilder sql = new StringBuilder();
            if(cubeOrrollupOrGroupingsets == 3){
                int index = 0;
                for (int i = 0; i < groupingSets.size(); i++) {
                    StringBuilder tmpSql = new StringBuilder();
                    tmpSql.append("(");
                    for (int j = 0; j < groupingSets.size(); j++) {
                        if(index >= groupbyItems.size()){
                            break;
                        }else {
                            tmpSql.append(groupbyItems.get(index++).toSqlClose());
                            if(groupingSets.get(i) > 1 && j != groupingSets.get(i) -1){
                                tmpSql.append(",");
                            }
                        }
                    }
                    tmpSql.append(")");
                    if(i!=groupingSets.size()-1){
                        tmpSql.append(",");
                    }
                    sql.append(tmpSql);
                }
                if(groupingSets.size() == 1){
                    return String.format(" GROUP BY GROUPING SETS %s",sql.toString());
                }else {
                    return String.format(" GROUP BY GROUPING SETS (%s)",sql.toString());
                }
            }else{
                sql.append(groupbyItems.get(0).toSql());
                for (int i = 0; i < itemSize; i++) {
                    sql.append(" , "+groupbyItems.get(i).toSql());
                }
            }

            if (cubeOrrollupOrGroupingsets == 1) {
                //1表示cube余令为真 生成cube子台
                return String.format(" GROUP BY CUBE( %s) ", sql.toString());
            } else if (cubeOrrollupOrGroupingsets == 2) {
                //2亲示rollup命令为直 生成rollup于
                return String.format("GROUP BY ROLLUP( %s) ", sql.toString());
            } else {
                //0 表示rollup命令、cube命令都为假 生成groupby子句
                return String.format(" GROUP BY %s", sql.toString());
            }
        }
    }

    @Override
    public void fill(GlobalState globalState) {
        //selecte经通元言成后,此处可以不填充
        if (!isCompleted) {
            for (int i = 0; i < itemSize; i++) {
                groupbyItems.get(i).fill(globalState);
            }
            isCompleted = true;
        }

    }

    //用查询列填充
    //返回groupby子句实际拥有的分组项数目
    public int fillBySelElement(DmSelectElements selElements) {
        int i = 0;
        int j = 0;
        for (i = 0, j = 0; i < selElements.elements_size && j < itemSize; i++) {
            if (selElements.elements.get(i).getDept() == 1) {
                //将非子查询的查询列
                groupbyItems.add(selElements.elements.get(i));
                j++;
            }
        }
        if (j < itemSize) {
            itemSize = j;
            modifyGroupingSets(itemSize);
        }
        return itemSize;
    }

    public List<Integer> modifyGroupingSets(int itemSize){
        int sum = 0;
        List<Integer> result = new ArrayList<>();
        for (int n = 0; n < groupingSets.size(); n++) {
            sum += groupingSets.get(n);
            if(sum < itemSize){
                result.add(groupingSets.get(n));
            }else {
                result.add(groupingSets.get(n) - (sum - itemSize));
                break;
            }
        }
        for(int tmp:result){
            groupingSets.clear();
            groupingSets.add(tmp);
        }
        return groupingSets;
    }

    //给cubORrollup赋值
    public int setCubeOrrollupOrGroupingsets(int cubeOrrollupOrGroupingsets) {
        this.cubeOrrollupOrGroupingsets = cubeOrrollupOrGroupingsets;
        return cubeOrrollupOrGroupingsets;
    }
}

